package com.sc.nft.controller;

import cn.hutool.core.lang.Assert;
import cn.hutool.core.util.ObjectUtil;
import com.sc.nft.annotation.UserLogin;
import com.sc.nft.controller.request.IdRequest;
import com.sc.nft.entity.UserInfo;
import com.sc.nft.entity.vo.CreateOrderVO;
import com.sc.nft.entity.vo.UserBusinessCardOrderPageVO;
import com.sc.nft.enums.RedisKeyEnum;
import com.sc.nft.exception.GlobalException;
import com.sc.nft.exception.GlobalRunTimeException;
import com.sc.nft.pool.UserPool;
import com.sc.nft.service.BusinessCardOrderService;
import com.sc.nft.sup.ErrorCode;
import com.sc.nft.sup.PageRequest;
import com.sc.nft.sup.PageResult;
import com.sc.nft.sup.Result;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.redisson.Redisson;
import org.redisson.api.RLock;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.validation.Valid;
import java.util.concurrent.TimeUnit;

@Slf4j
@RequiredArgsConstructor
@RestController
@RequestMapping("/order/businessCardOrder")
@Api(tags = "用户名片")
public class BusinessCardOrderController {
    private final Redisson redisson;
    private final RedisTemplate redisTemplate;
    private final BusinessCardOrderService businessCardOrderService;


    @ApiOperation(value = "创建订单", notes = "创建订单", httpMethod = "POST", produces = MediaType.APPLICATION_JSON_VALUE)
    @PostMapping(value = "/createOrder", produces = MediaType.APPLICATION_JSON_VALUE)
    @UserLogin
    public Result<CreateOrderVO> createOrder() throws GlobalException {
        UserInfo user = UserPool.getUser();
        CreateOrderVO order = null;
        RLock lock = redisson.getLock(RedisKeyEnum.BUSINESS_CARD_ORDER_CREATE.getKey() + user.getId());
        try {
            boolean res = lock.tryLock(3, 10, TimeUnit.SECONDS);
            if (res) {
                order = businessCardOrderService.createOrder(user);
            } else {
                return Result.fail(ErrorCode.LATER_TRY);
            }
        } catch (InterruptedException e) {
            return Result.fail("当前人数过多，请稍后再试");
        } finally {
            if (lock.isLocked() && lock.isHeldByCurrentThread()) {
                lock.unlock();
            }
        }
        return Result.success(order);
    }

    @PostMapping(value = "/userBusinessCardOrderPage", produces = MediaType.APPLICATION_JSON_VALUE)
    @ApiOperation(value = "订单列表", notes = "订单列表", httpMethod = "POST", produces = MediaType.APPLICATION_JSON_VALUE)
    @UserLogin
    public PageResult<UserBusinessCardOrderPageVO> userBusinessCardOrderPage(@RequestBody PageRequest request) {
        UserInfo user = UserPool.getUser();
        Assert.isTrue(ObjectUtil.isNotNull(user), () -> new GlobalRunTimeException("用户不存在"));
        return PageResult.success(businessCardOrderService.userBusinessCardOrderPage(request.toMp(), user.getId()));
    }


    @ApiOperation(value = "订单成功状态", notes = "订单成功状态", httpMethod = "POST", produces = MediaType.APPLICATION_JSON_VALUE)
    @PostMapping(value = "/orderSuccessStatus", produces = MediaType.APPLICATION_JSON_VALUE)
    @UserLogin
    public Result orderSuccessStatus(@Valid @RequestBody IdRequest idRequest) {
        return Result.success(businessCardOrderService.orderSuccessStatus(idRequest.getId()));
    }



    @ApiOperation(value = "关闭订单", notes = "关闭订单", httpMethod = "POST", produces = MediaType.APPLICATION_JSON_VALUE)
    @PostMapping(value = "/closeOrder", produces = MediaType.APPLICATION_JSON_VALUE)
    @UserLogin
    public Result closeOrder(@Valid @RequestBody IdRequest idRequest) {
        businessCardOrderService.closeOrder(idRequest.getId());
        return Result.success();
    }

    @ApiOperation(value = "2次付款的时候,订单数据", notes = "2次付款的时候,订单数据", httpMethod = "POST", produces = MediaType.APPLICATION_JSON_VALUE)
    @PostMapping(value = "/secondaryPayment", produces = MediaType.APPLICATION_JSON_VALUE)
    @UserLogin
    public Result<CreateOrderVO> secondaryPayment(@Valid @RequestBody IdRequest idRequest) {
        return Result.success(businessCardOrderService.secondaryPayment(idRequest.getId()));
    }
}
